local CombatImpl = require("combat.CombatImpl")
local TargetMode = require("combat.TargetMode")
local CombatCalc = require("combat.CombatCalc")
local CombatObj = require("combat.CombatObj")
local RoleDefine = require("role.RoleDefine")
local CombatBuff = require("combat.CombatBuff")
local CombatDefine = require("combat.CombatDefine")
local BeSkill = require("combat.BeSkill")
local Util = require("common.Util")
local SkillExcel = require("excel.skill").skill
local CmdExcel = require("excel.skill").cmd
local ProjectLogic = require("platform.ProjectLogic")
local BufferExcel = require("excel.buffer")

function setSkill(obj,config,skinConfig)
	config = skinConfig or config
	obj.skillList = {}
	local skillList = obj.skillList
	local len = 0
	local skillConfig
	local normalAtkID = config.normalAtkID
	--普通技能
	if normalAtkID then
		len = len + 1
		skillConfig = SkillExcel[normalAtkID]
		obj.skillList[len] = {normalAtkID,skillConfig.cd[1] or 0,skillConfig.cd[2] or 0}--skillID,开始使用回合，冷切回合
	end

	--主动技能
    local temp = {}
	for _,skillID in ipairs(config.skillList) do
		len = len + 1
		skillConfig = SkillExcel[skillID]
        if not temp[skillID] and skillConfig and skillConfig.need <= obj.quality then
		   obj.skillList[len] = {skillID,skillConfig.cd[1] or 0,skillConfig.cd[2] or 0}--skillID,开始使用回合，冷切回合
           temp[skillID] = 1
        end
	end

	if len > 1 then
		table.sort(obj.skillList,function(a,b)
			return a[3] > b[3]
		end)
	end
end


CMD2ID = {}
function initAfterHot()
	for k,v in pairs(CMD2ID) do
		CMD2ID[k] = nil
	end
	for k,v in pairs(CmdExcel) do
		CMD2ID[v.cmd] = k
	end
end

function getCMD2ID(cmd) 
	return CMD2ID[cmd]
end
GroupSkillCnt = 0--技能包触发技能次数
local function realUse(obj, skillID, fanjiTargets,otherArgs)
	local skillConfig = SkillExcel[skillID]
	CombatImpl.nowAttacker	= obj
	if skillConfig  then
        
        --直接伤害
		CombatCalc.initAttacker(obj)
		--print("skill realuse:",obj.pos,skillID,skillConfig.targetMode[1],skillConfig.targetMode[2])
		local targets = TargetMode.getTargets(obj, skillConfig.targetMode, fanjiTargets, nil , true,skillConfig.type == CombatDefine.SKILL_TYPE1,skillID)
		local len = #targets
		if len < 1 then return end
        for i=1, len do
           local defobj = targets[i]
           CombatCalc.initAttacker(defobj)
        end

		GroupSkillCnt = GroupSkillCnt + 1
        -- 复活技能不走这里
        if skillConfig.cmd ~= "revive" then
		   CombatImpl.addFrame()
		   CombatImpl.setSkillID(obj, skillID)
		   CombatImpl.setSaySkill(obj.pos,skillConfig.id,skillConfig.contentType)
	    end


		attack(obj, targets, skillConfig)

		if not fanjiTargets and skillConfig.otherArgs.addBuffBeforeCmd then
			CombatBuff.onHit(obj,targets,skillConfig)
		end

		--额外作用
		local cmdTargets
		if CMD[skillConfig.cmd] then
		   cmdTargets = CMD[skillConfig.cmd](obj, skillConfig, targets)
		end
        
		if not fanjiTargets then
			if not skillConfig.otherArgs.addBuffBeforeCmd then
				CombatBuff.onHit(obj,targets,skillConfig,cmdTargets,otherArgs)
			end
		end
		BeSkill.onHit(obj,targets,skillID)
        
		CombatImpl.totalAtkCnt = CombatImpl.totalAtkCnt + 1
	end
	CombatImpl.nowAttacker	= nil
end

function use(obj, skillID, fanjiTargets)
	local skillConfig = SkillExcel[skillID]
	GroupSkillCnt = 0
	if skillConfig.type == CombatDefine.SKILL_TYPE5 then
		for k,v in ipairs(skillConfig.otherArgs.skillList) do
			local config = SkillExcel[v]
			local targets = TargetMode.getTargets(obj, config.targetMode,fanjiTargets, nil , true)
			if #targets > 0 then
				realUse(obj, v,fanjiTargets)
				return
			end
		end
	elseif skillConfig.type == CombatDefine.SKILL_TYPE6 then
		for k,v in ipairs(skillConfig.otherArgs.skillList) do
			local config = SkillExcel[v]
			local targets = TargetMode.getTargets(obj, config.targetMode,fanjiTargets, nil , true)
			if #targets > 0 then
				realUse(obj, v,fanjiTargets,{noFirst = (k ~= 1)})
			end
		end
	elseif skillConfig.type == CombatDefine.SKILL_TYPE7 then
		local r = math.random(1,10000)
		for k,v in ipairs(skillConfig.otherArgs.skillList) do
			if r <= v[1] then
				local config = SkillExcel[v[2]]
				local targets = TargetMode.getTargets(obj, config.targetMode,fanjiTargets, nil , true)
				if #targets > 0 then
					realUse(obj, v[2], fanjiTargets)
				end
				return
			else
				r = r - v[1]
			end
		end 
	else
		realUse(obj, skillID,fanjiTargets)
	end
end

local hitList = {}
local flagList = {}
function attack(obj, targets, skillConfig)
	if not skillConfig.hurtRate[1] then obj.isAllCalcHp = true return end

    local totalHurt = 0 
    local limitHurt = 0
    local fenTanHurt = 0
    if  skillConfig.otherArgs and skillConfig.otherArgs.hurtFenTan and skillConfig.otherArgs.hurtFenTan[1] == 1  then
        for index = 1, #targets do
		   local target = targets[index]
		   if target.hp > 0 then
              local hurt, flag = CombatCalc.calcHurt(obj, index, targets, skillConfig)
              totalHurt = totalHurt + hurt
              fenTanHurt = totalHurt / #targets
              limitHurt = CombatObj.getValue(obj,RoleDefine.ATK) * skillConfig.otherArgs.hurtFenTan[2]
              if fenTanHurt >= limitHurt then
                 fenTanHurt = limitHurt
              end
              flagList[index] = flagList[index] or 0
              flagList[index] = flag
           end
        end
    end

    local len = 0
    obj.isAllCalcHp = nil
    if #targets == 0 then
       obj.isAllCalcHp = true
    end
	for index = 1, #targets do
		local target = targets[index]
		if target.hp > 0 then
			BeSkill.beforeHit(obj,target)
            local hurt,flag = nil
            if fenTanHurt == 0 then
			   hurt,flag = CombatCalc.calcHurt(obj, index, targets, skillConfig)
               target.isShanBi = Util.getBit(flag, CombatDefine.FLAG_SHANBI)
            else
               hurt = fenTanHurt 
               flag = flagList[index]
            end
            -- 闪避不处理目标被动技能
            obj.isAllCalcHp = index == #targets
			target.attackSkillID = skillConfig.id
			local hpValue,srcValue = 0,0
			if hurt > 0 then
				hpValue,srcValue = CombatObj.updateHp(target, -hurt,nil,true, obj.pos,CombatObj.SKILL_HP_TYPE)
				CombatObj.onHpCB(target,hpValue,obj.pos,skillConfig.id)
			end
			CombatImpl.setSkillHit(target,srcValue,nil,flag,obj,skillConfig.id)
			
            if target.isShanBi ~= 1 then
               len = len + 1
               hitList[len] = target
               BeSkill.afterHit(obj,target)
            end
			target.attackSkillID = nil
		end
	end

    -- 处理命中列表
    for index = 1, #targets do
       targets[index] = nil
    end

    for index = 1, len do
		targets[index] = hitList[index]
    end
end


local function calcHp(attacker,target,calcType,rate,limit,isAddHp,param, flag)
	local hp = CombatCalc.calcHp(attacker,target,calcType,rate, isAddHp, flag)
	if param and param.targetCnt then
		hp = hp / param.targetCnt
	end
	if limit then
		if hp > limit then
			hp = limit
		end
	end
	return hp
end

CMD = {}
function CMD.hp(obj,skillConfig,skillTargets)
	local ret = {}
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if args[4] and r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3], skillTargets)
	local targetCnt = #targets
	local hp
	local limit
	if args[5] and args[5] > 0 then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	if not obj.isPet and args[6] and args[6] > 0 then
		limit = args[6] * CombatObj.getHpMax(obj) / 10000
	end

	local hpAddRate = CombatObj.getValue(obj,RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
	for _,target in ipairs(targets) do
		if not target.bufferCmd["noHp"] then
			hp = calcHp(obj,target,calcType,rate,limit,true)
			hp = hp * (1 + hpAddRate)
			hp = hp < 0 and 1 or hp

            if hp > 0 and obj.isAllCalcHp == true then
                if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                local showHp = hp
                if hp > 0 and d < 0 then
                   showHp = hp * (-1)
                end
				CombatImpl.setExtraHit(target, showHp, CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)
            end 

			if hp < 0 then
				if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                if hp > 0 and d < 0 then
                   hp = hp * (-1)
                end
				CombatImpl.setExtraHit(target, hp, CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)
			end
			ret[#ret+1] = target
		end
	end
	return ret
end

function CMD.speedHp(obj,skillConfig,skillTargets)
	if not (skillTargets and skillTargets[1]) then
		return
	end
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if args[4] and r > args[4] then 
		return
	end
	
	local calcType = args[1]
	local rate = args[2]
	local target = skillTargets[1]
	local ret = {}
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local hpAddRate = CombatObj.getValue(obj,RoleDefine.ZAOCHENG_HP_ADD_RATE) / 10000
	
	local aSpeed = CombatImpl.getValue(obj,RoleDefine.SPEED)
	local bSpeed = CombatImpl.getValue(target,RoleDefine.SPEED)
	local checkSpeed = aSpeed - bSpeed
	if args[3] == 1 then
		checkSpeed = -checkSpeed
	end
	if checkSpeed > 0 then
		local targets = TargetMode.getTargets(obj, args[3], skillTargets)
		for _,target in ipairs(targets) do
			hp = calcHp(obj,target,calcType,rate,limit,true)
			hp = hp * (1 + hpAddRate)
			hp = hp < 0 and 1 or hp
			if hp ~= 0 and not target.bufferCmd["noHp"] then
				if target.side == CombatDefine.DEFEND_SIDE then
					hp = CombatImpl.commonArgs.hpLimit or hp
				end
				local d = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
                if hp > 0 and d < 0 then
                   hp = hp * (-1)
                end
				CombatImpl.setExtraHit(target,hp,CMD2ID["hp"])
				CombatObj.onHpCB(target,d, obj.pos)
			end
			ret[#ret+1] = target
		end
	end
	return ret
end

function CMD.statusHp(obj,skillConfig,skillTargets)
	if not skillTargets then
		return
	end
	local isAdd = false
	local args = obj.isPet and obj.args or skillConfig.args
	for _,v in ipairs(skillTargets) do
		if CombatBuff.isStatus(v,args[4]) then
			isAdd = true
			break
		end 
	end
	if not isAdd then return end
	
	
	local calcType = args[1]
	local rate = args[2]
	local ret = {}
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local targets = TargetMode.getTargets(obj, args[3], skillTargets)
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit,true)
		hp = hp < 0 and 1 or hp
		if hp ~= 0 and not target.bufferCmd["noHp"] then
			if target.side == CombatDefine.DEFEND_SIDE then
				hp = CombatImpl.commonArgs.hpLimit or hp
			end
			local d = CombatObj.updateHp(target,hp,nil,true,obj.pos,CombatObj.EXTRA_HP_TYPE)
            if hp > 0 and d < 0 then
               hp = hp * (-1)
            end
			CombatImpl.setExtraHit(target,hp,CMD2ID["hp"])
			CombatObj.onHpCB(target,d, obj.pos)
		end
		ret[#ret+1] = target
	end
	return ret
end

function CMD.hurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurt"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.behurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		if calcType ~= 17 then
			hp = calcHp(target,obj,calcType,rate,limit)
		else
			hp = calcHp(obj, target,calcType,rate,limit)
		end
		
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["behurt"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.hurtwalun(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtwalun"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.posHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	
    local posList = args[6]
	if posList == nil then
		return
	end

	for _,target in ipairs(targets) do
		local bfind = false
		for k, v in pairs(posList) do
			if v == target.pos then
				bfind = true
				break
			end
		end
		
	    if bfind  then
			hp = calcHp(obj,target,calcType,rate,limit, false)
			if hp ~= 0 then
				local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["hurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end
			end
		end
	end
	return ret
end

function CMD.hurtxia(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtxia"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.hurtmingli(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtmingli"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.hurtmingli2(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtmingli2"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.hurtguangci(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtguangci"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end

function CMD.jobHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local calcType = args[1]
	local rate = args[2]
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local job = args[4]
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local ret = {}
	for _,target in ipairs(skillTargets) do
		if target.job == job then
			hp = calcHp(obj,target,calcType,rate,limit)
			if hp and hp ~= 0 then
				local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["jobHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end
			end
		end
	end	
	return ret
end


function CMD.statusHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local calcType = args[1]
	local rate = args[2]
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local status = args[4]
	local hp
	local limit
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end

	local ret = {}
	for _,target in ipairs(skillTargets) do
		if CombatBuff.isStatus(target, status)  then
			hp = calcHp(obj,target,calcType,rate,limit)
			if hp and hp ~= 0 then
				local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["jobHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end
			end
		end
	end	
	return ret
end

function CMD.hpHurt(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local calcType = args[1]
	local rate = args[2]
	local hpRate = args[3]/10000
	local ret = {}
	for _,target in ipairs(skillTargets) do
		local hpLimit = CombatObj.getHpMax(target) * hpRate
		if target.hp >= hpLimit then
			hp = calcHp(obj,target,calcType,rate)
			if hp and hp ~= 0 then
				local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["hpHurt"])
					CombatObj.onHpCB(target,d, obj.pos)
					ret[#ret+1] = target
				end
			end
		end
	end	
	return ret
end

function CMD.fanji(obj,skillConfig,skillTargets)
	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	if CombatBuff.isStatus(obj,{"xuanyun","shihua","bingdong"}) then return end
	if obj.side == skillTargets[1].side then
		return
	end
	if obj.hp > 0 then
		local r = math.random(0,10000)
		if r < skillConfig.args[2] then
			CombatImpl.fanjiList[#CombatImpl.fanjiList + 1] = {obj,skillConfig.args[1],skillTargets}
		end
	end
end

function CMD.qingsuan(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local rate = args[1]
	local limit
	if args[4] then
		limit = args[4] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	local targets = TargetMode.getTargets(obj, args[2],skillTargets)
	local ret = {}
	for _,target in ipairs(targets) do
		local baseValue = CombatBuff.qingsuan(target)
		if baseValue > 0 then
			local hurt = baseValue * rate / 10000
			if limit and hurt > limit then
				hurt = limit
			end
			local d = CombatObj.updateHp(target,-hurt,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			CombatImpl.setExtraHit(target,-hurt,CMD2ID["qingsuan"])
			CombatObj.onHpCB(target,d, obj.pos)
			ret[#ret+1] = target
		end
	end
	return ret
end

function CMD.jiekong(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[2] then
		return
	end
	local targets = TargetMode.getTargets(obj, args[1],skillTargets)
	local ret = {}
	for _,target in ipairs(targets) do
		CombatBuff.jiekong(target)
		ret[#ret+1] = target
	end
	return ret
end

function CMD.groupcmd(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	for k,v in ipairs(skillConfig.args) do
		local cmd = v[1]
		local conf = {args = v[2]}
		if CMD[cmd] then
			CMD[cmd](obj,conf,skillTargets)
		end
	end
	return {}
end

function CMD.randcmd(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	local total = 0
	for k,v in ipairs(skillConfig.args) do
		total = total + v[3]
	end
	local r = math.random(0,total)
	for k,v in ipairs(skillConfig.args) do
		if r <= v[3] then
			local cmd = v[1]
			local conf = {args = v[2]}
			if CMD[cmd] then
				CMD[cmd](obj,conf,skillTargets)
			end
			break
		else
			r = r - v[1]
		end
	end	

	return {}
end

function CMD.qusan(obj,skillConfig,skillTargets)
	if obj.isPet then return {} end
	
	local args = skillConfig.args
	local r = math.random(0,10000)
	if r > args[3] then
		return
	end
	local qusanType = args[1]
	local calcType = args[5] and args[5][1]
	local rate = args[5] and args[5][2]
    local buffers = args[8] and args[8][1]

	local targets = TargetMode.getTargets(obj, args[2],skillTargets)
	local ret = {}
	if args[7] then
		limit = args[7] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		local cnt = CombatBuff.qusan(target, qusanType,args[4])
		if limit then
			limit = limit * cnt
		end

        if buffers and cnt > 0 then
           local targets = TargetMode.getTargets(obj, args[8][2],skillTargets)
           CombatBuff.qusanAddBuff(obj, targets, buffers)
        end

		ret[#ret+1] = target
		if calcType and rate and cnt > 0 then
			local hp = calcHp(obj,target,calcType,rate * cnt, limit, nil, nil, args[6])
			if hp ~= 0 then
				local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
				if d ~= 0 then
					CombatImpl.setExtraHit(target,-hp,CMD2ID["qusan"])
					CombatObj.onHpCB(target,d, obj.pos)
				end
			end
		end
	end

	return ret
end


function CMD.hurtwalun2(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtwalun2"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end


function CMD.hurtxia2(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtxia2"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end


function CMD.hurtxia3(obj,skillConfig,skillTargets)
	local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK_COMBAT_NOW) / 10000
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurtxia3"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end


NO_SKILL_CHECK_COMBO_LIST = {
	["hp"] = 1,
	["revive"] = 1,
	["baohu"] = 1,
}
function skillIsHpOrRevive(argSkillID)
    local argSkillConf = SkillExcel[argSkillID]
    if  not argSkillConf  then return end

    -- 带有伤害
    if argSkillConf.hurtRate[1] then return end

    if argSkillConf.continuous and argSkillConf.continuous == 1 then return true end

    if NO_SKILL_CHECK_COMBO_LIST[argSkillConf.cmd] then
       return true
    end

    local bRet = false
    if argSkillConf.cmd == "groupcmd" then
        for k,v in ipairs(argSkillConf.args) do
		   local cmd = v[1]
           if cmd == "hurt" then return end
           if NO_SKILL_CHECK_COMBO_LIST[cmd] then
              bRet = true
           end
        end
    end

    -- 技能包
    if argSkillConf.type == CombatDefine.SKILL_TYPE5 or 
       argSkillConf.type == CombatDefine.SKILL_TYPE6 or
       argSkillConf.type == CombatDefine.SKILL_TYPE7 then
        for k,v in ipairs(argSkillConf.otherArgs.skillList) do
		  local config = SkillExcel[v]
          -- 带有伤害
		  if config and config.hurtRate[1] then return end

          if config then
             if NO_SKILL_CHECK_COMBO_LIST[config.cmd] or config.continuous == 1 then
                bRet = true
             end
          
          
            for k,v in ipairs(config.buffers) do
		       local bufConfig = BufferExcel.buffer[v[1]]
               -- 带有伤害
               if bufConfig and NO_SKILL_CHECK_COMBO_LIST[bufConfig.cmd] then
                  bRet = true
               end 
	        end
		  end
	   end

       for k,v in ipairs(argSkillConf.buffers) do
		  local bufConfig = BufferExcel[v[1]]
            -- 带有伤害
          if bufConfig and NO_SKILL_CHECK_COMBO_LIST[bufConfig.cmd] then
             bRet = true
          end 
	   end
   end

   return bRet
end


function CMD.combo(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(argSkillID) then
           return
       end

       if skillIsHpOrRevive(skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1, skillConfig.args[5]}
		return true
	end
end

--
function CMD.comboFight(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(argSkillID) then
           return
       end

       if skillIsHpOrRevive(skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji then return end
	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1, skillConfig.args[5]}
		return true
	end
end

function CMD.combo1(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(skillConfig) then
           return
       end

       if skillIsHpOrRevive(skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],2}
		return true
	end
end

function CMD.combo2(obj,skillConfig,skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getSkillID(obj)
       if skillIsHpOrRevive(argSkillID) then
           return
       end

       if skillIsHpOrRevive(skillConfig.id) then
           return
       end
    end

	if CombatImpl.isFanji or CombatImpl.comboType > 0 then return end
	if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 1, skillConfig.args[2], skillConfig.args[3],3}
		return true
	end
end


function CMD.comboNormal(obj, skillConfig, skillTargets)
    -- 二次元 屏蔽 治疗 复活的连击
    if ProjectLogic.isSsecy() then
       local argSkillID = skillConfig.args[3] or CombatImpl.getNormalSkill(obj)
       if skillIsHpOrRevive(argSkillID) then
           return
       end

       if skillIsHpOrRevive(skillConfig.id) then
           return
       end
    end

	if CombatImpl.comboType > 0 then return end

    if CombatImpl.isFanji then
        if GroupSkillCnt > 2 then return end
    else
        if GroupSkillCnt ~= 1 then return end--技能包首次技能攻击才能触发
    end
	
	local r = math.random(0,10000)
	if r < skillConfig.args[1] then	
		CombatImpl.comboList[#CombatImpl.comboList + 1] = {obj, 2, skillConfig.args[2], skillConfig.args[3],skillConfig.args[4] or 1}
	end
end

function CMD.baohu(obj,skillConfig,skillTargets)
	local d = CombatObj.updateHp(obj,obj.baohuHurt,nil,nil, obj.pos,CombatObj.BUFFER_HP_TYPE)
	if d ~= 0 then
		local attrs = {}
		attrs[RoleDefine.BAOHU_COMBAT] = skillTargets[1].pos
		CombatImpl.setExtraHit(obj,d,CMD2ID["baohu"],attrs)
		CombatObj.onHpCB(obj,d, skillTargets[1].pos)
	end	
end

function CMD.yinbaoZuzhou(obj,skillConfig,skillTargets)
	CombatBuff.yinbaoZuzhou(obj, skillTargets, skillConfig)
end

--指定普攻目标模式
function CMD.normalTarget(obj,skillConfig)
	obj.normalTarget = {status = {}}
	if skillConfig.args.status then
		for k,v in ipairs(skillConfig.args.status) do
			obj.normalTarget.status[k] = v
		end
	end
end

--诅咒附加伤害
function CMD.zuzhouHurt(obj, skillConfig, skillTargets)
    if not obj.args then return end
    local confArgs = skillConfig.args
	local targets = TargetMode.getTargets(obj, confArgs[1], skillTargets)
	local zuzhouHurt = obj.args * confArgs[2] / 10000
	for _,target in ipairs(targets) do
		if zuzhouHurt ~= 0 then
			local d = CombatObj.updateHp(target,-zuzhouHurt,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-zuzhouHurt,CMD2ID["zuzhouHurt"])
				CombatObj.onHpCB(target,d, obj.pos)
			end
		end
	end
    obj.args = nil
end


function CMD.dnexhurt(obj,skillConfig,skillTargets)
    local args = obj.isPet and obj.args or skillConfig.args
	local r = math.random(0,10000)
	if r > args[4] then 
		return
	end
	local calcType = args[1]
	local rate = args[2]
	local targets = TargetMode.getTargets(obj, args[3],skillTargets)
	local hp
	local limit
	local ret = {}
	if args[5] then
		limit = args[5] * CombatObj.getValue(obj,RoleDefine.ATK)
	end
	for _,target in ipairs(targets) do
		hp = calcHp(obj,target,calcType,rate,limit)
		if hp ~= 0 then
			local d = CombatObj.updateHp(target,-hp,nil,true, obj.pos,CombatObj.EXTRA_HP_TYPE)
			if d ~= 0 then
				CombatImpl.setExtraHit(target,-hp,CMD2ID["hurt"])
				CombatObj.onHpCB(target,d, obj.pos)
				ret[#ret+1] = target
			end
		end
	end
	return ret
end